package fr.nts.framework.front.form.validation.validator;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import fr.nts.framework.front.form.validation.FieldValidationResult;
import fr.nts.framework.front.form.validation.annotation.NumberConstraint;

/**
 * Définit les règles pour valider un nombre d'un formulaire NTS
 * 
 * @author sco
 * @version 1.0.0
 */
@Component("numberValidator")
public class NumberValidator implements Validator<NumberConstraint>{
	 
	private static final String MAX_ERROR_CODE = "number.constraint.max";
	private static final String MIN_ERROR_CODE = "number.constraint.min";
	private static final String NOT_NULL_CODE = "number.constraint.not.null";
	 
	/*
	 * (non-Javadoc)
	 * @see fr.nts.framework.front.form.validation.Validator#valid(java.lang.Object, java.lang.Object)
	 */
	@Override
	public FieldValidationResult valid(final String[] formValues, 
			                           final NumberConstraint rules){
		
		// Liste globale des erreurs
		Map<String,List<String>> errorsMap = Maps.newHashMap();
		
		// Pour chaque champ à tester
		for(String value: formValues){
			List<String> errors = Lists.newArrayList();
			
			// Règle not null
			if(rules.notNull() && StringUtils.isEmpty(value)){
				errors.add(NOT_NULL_CODE);
			}
			
			// Règle max
			if(!StringUtils.isEmpty(value) && rules.max() >= 0){
				boolean result = true;
		
				if(!rules.decimal()){		
					try{
						Long numberValue = Long.valueOf(value);
						
						if(numberValue > rules.max()){
							result = false;
						}
					}catch(NumberFormatException e){
						result = false;
					}
				}else{
					try{
						Float numberValue = Float.valueOf(value);
						
						if(numberValue > rules.max()){
							result = false;
						}
					}catch(NumberFormatException e){
						result = false;
					}
				}
				
				if(!result){
					errors.add(MAX_ERROR_CODE);
				}
			}
			
			
			// Règle min
			if(!StringUtils.isEmpty(value) && rules.min() >= 0){
				boolean result = true;
		
				if(!rules.decimal()){		
					try{
						Long numberValue = Long.valueOf(value);
						
						if(numberValue < rules.min()){
							result = false;
						}
					}catch(NumberFormatException e){
						result = false;
					}
				}else{
					try{
						Float numberValue = Float.valueOf(value);
						
						if(numberValue < rules.min()){
							result = false;
						}
					}catch(NumberFormatException e){
						result = false;
					}
				}
				
				if(!result){
					errors.add(MIN_ERROR_CODE);
				}
			}
			
			if(!errors.isEmpty()){
				errorsMap.put(value, 
					          errors);
			}
		}
		
		// Résultat final
		if(!errorsMap.isEmpty()){
			return new FieldValidationResult(errorsMap);
		}else{
			return FieldValidationResult.ok;
		}
	}
}